package com.suredy.app.dm.ctrl;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import com.suredy.app.dm.constants.DmOpTypes;
import com.suredy.app.dm.model.DmOpLog;
import com.suredy.app.dm.srv.DmOpLogSrv;
import com.suredy.app.porject.model.Bid;
import com.suredy.app.porject.model.BidAgency;
import com.suredy.app.porject.model.Biddinger;
import com.suredy.app.porject.model.Contract;
import com.suredy.app.porject.model.embedded.BidAgencyInfo;
import com.suredy.app.porject.model.embedded.BiddingerInfo;
import com.suredy.app.porject.model.vo.BidEditModel;
import com.suredy.app.porject.model.vo.MainContractEditModel;
import com.suredy.app.porject.service.BidAgencySrv;
import com.suredy.app.porject.service.BiddingerSrv;
import com.suredy.core.ctrl.BaseCtrl;

/**
 * 数据维护入口
 * 
 * @author VIVID.G
 * @since 2016-3-31
 * @version v0.1
 */
public class DataManagerCtrlHelper extends BaseCtrl {

	@Autowired
	protected DmOpLogSrv dmOpLogSrv;

	@Autowired
	protected BiddingerSrv biddingerSrv;

	@Autowired
	protected BidAgencySrv bidAgencySrv;

	protected void recordBidDelLog(List<Bid> bids) {
		if (bids == null || bids.isEmpty())
			return;

		DmOpLog log = this.newLog(DmOpTypes.DM_001_DELETE);

		if (log == null)
			throw new RuntimeException("Can not create op log.");

		StringBuilder logs = new StringBuilder("投标数据：");

		for (Bid b : bids) {
			logs.append("\n编号：");
			logs.append(b.getProjectNo());
			logs.append("\t名称：");
			logs.append(b.getName());
		}

		log.setLogs(logs.toString());

		this.dmOpLogSrv.save(log);
	}

	protected void recordContractDelLog(List<Contract> contract) {
		if (contract == null || contract.isEmpty())
			return;

		DmOpLog log = this.newLog(DmOpTypes.DM_001_DELETE);

		if (log == null)
			throw new RuntimeException("Can not create op log.");

		StringBuilder logs = new StringBuilder("合同数据：");

		for (Contract c : contract) {
			logs.append("\n编号：");
			logs.append(c.getNo());
			logs.append("\t，名称：");
			logs.append(c.getName());
		}

		log.setLogs(logs.toString());

		this.dmOpLogSrv.save(log);
	}

	protected void recordBidUpdateLog(BidEditModel old, BidEditModel now) {
		if (old == null || now == null)
			return;

		DmOpLog log = this.newBidUpdateLog(old, now);

		if (log == null)
			return;

		this.dmOpLogSrv.save(log);
	}

	protected void recordContractUpdateLog(MainContractEditModel old, MainContractEditModel now) {
		if (old == null || now == null)
			return;

		DmOpLog log = this.newContractUpdateLog(old, now);

		if (log == null)
			return;

		this.dmOpLogSrv.save(log);
	}

	private DmOpLog newBidUpdateLog(BidEditModel old, BidEditModel now) {
		DmOpLog log = this.newLog(DmOpTypes.DM_002_UPDATE);

		if (log == null)
			throw new RuntimeException("Can not create op log.");

		boolean modify = false;
		StringBuilder logs = new StringBuilder("投标数据：");

		if (!this.isDataEqual(old.getQuotationType(), now.getQuotationType())) {
			logs.append("\n报价方式：");
			logs.append(old.getQuotationType());
			logs.append(" --> ");
			logs.append(now.getQuotationType());
			modify = true;
		}
		if (!this.isDataEqual(old.getName(), now.getName())) {
			logs.append("\n项目名称：");
			logs.append(old.getName());
			logs.append(" --> ");
			logs.append(now.getName());
			modify = true;
		}
		if (!this.isDataEqual(old.getProjectNo(), now.getProjectNo())) {
			logs.append("\n投标编号：");
			logs.append(old.getProjectNo());
			logs.append(" --> ");
			logs.append(now.getProjectNo());
			modify = true;
		}
		if (!this.isDataEqual(old.getBidNo(), now.getBidNo())) {
			logs.append("\n招标编号：");
			logs.append(old.getBidNo());
			logs.append(" --> ");
			logs.append(now.getBidNo());
			modify = true;
		}
		if (!this.isDataEqual(old.getExecutor(), now.getExecutor())) {
			logs.append("\n授权代理人：");
			logs.append(old.getExecutor());
			logs.append(" --> ");
			logs.append(now.getExecutor());
			modify = true;
		}
		if (!this.isDataEqual(old.getBidType(), now.getBidType())) {
			logs.append("\n招标类型：");
			logs.append(old.getBidType());
			logs.append(" --> ");
			logs.append(now.getBidType());
			modify = true;
		}
		if (!this.isDataEqual(old.getBidWay(), now.getBidWay())) {
			logs.append("\n投标方式：");
			logs.append(old.getBidWay());
			logs.append(" --> ");
			logs.append(now.getBidWay());
			modify = true;
		}
		if (!this.isDataEqual(old.getSignDate(), now.getSignDate(), "yyyy-MM-dd")) {
			logs.append("\n报名时间：");
			logs.append(this.datetimeFormate(old.getSignDate(), "yyyy-MM-dd"));
			logs.append(" --> ");
			logs.append(this.datetimeFormate(now.getSignDate(), "yyyy-MM-dd"));
			modify = true;
		}
		if (!this.isDataEqual(old.getOpeningTime(), now.getOpeningTime(), "yyyy-MM-dd")) {
			logs.append("\n开标时间：");
			logs.append(this.datetimeFormate(old.getOpeningTime(), "yyyy-MM-dd"));
			logs.append(" --> ");
			logs.append(this.datetimeFormate(now.getOpeningTime(), "yyyy-MM-dd"));
			modify = true;
		}
		if (!this.isDataEqual(old.getOwnCompany(), now.getOwnCompany())) {
			logs.append("\n投标单位：");
			logs.append(old.getOwnCompany());
			logs.append(" --> ");
			logs.append(now.getOwnCompany());
			modify = true;
		}

		if (this.compareBiddingerInfo(old.getBiddingerInfo(), now.getBiddingerInfo(), logs))
			modify = true;

		if (this.compareBidAgencyInfo(old.getBidAgencyInfo(), now.getBidAgencyInfo(), logs))
			modify = true;

		if (!this.isDataEqual(old.getBidScope(), now.getBidScope())) {
			logs.append("\n招标范围：");
			logs.append(old.getBidScope());
			logs.append(" --> ");
			logs.append(now.getBidScope());
			modify = true;
		}
		if (!this.isDataEqual(old.getRemark(), now.getRemark())) {
			logs.append("\n备注：");
			logs.append(old.getRemark());
			logs.append(" --> ");
			logs.append(now.getRemark());
			modify = true;
		}

		if (!modify)
			return null;

		log.setLogs(logs.toString());

		return log;
	}

	private DmOpLog newContractUpdateLog(MainContractEditModel old, MainContractEditModel now) {
		DmOpLog log = this.newLog(DmOpTypes.DM_002_UPDATE);

		if (log == null)
			throw new RuntimeException("Can not create op log.");

		boolean modify = false;
		StringBuilder logs = new StringBuilder("合同数据：");

		if (!this.isDataEqual(old.getName(), now.getName())) {
			logs.append("\n合同名称：");
			logs.append(old.getName());
			logs.append(" --> ");
			logs.append(now.getName());
			modify = true;
		}
		if (!this.isDataEqual(old.getNo(), now.getNo())) {
			logs.append("\n合同编号：");
			logs.append(old.getNo());
			logs.append(" --> ");
			logs.append(now.getNo());
			modify = true;
		}
		if (!this.isDataEqual(old.getPrice(), now.getPrice())) {
			logs.append("\n合同金额：");
			logs.append(old.getPrice());
			logs.append(" --> ");
			logs.append(now.getPrice());
			modify = true;
		}
		if (!this.isDataEqual(old.getBjTime(), now.getBjTime(), "yyyy-MM-dd")) {
			logs.append("\n办结日期：");
			logs.append(this.datetimeFormate(old.getBjTime(), "yyyy-MM-dd"));
			logs.append(" --> ");
			logs.append(this.datetimeFormate(now.getBjTime(), "yyyy-MM-dd"));
			modify = true;
		}
		if (!this.isDataEqual(old.getContractStart(), now.getContractStart(), "yyyy-MM-dd")) {
			logs.append("\n合同起始工期：");
			logs.append(this.datetimeFormate(old.getContractStart(), "yyyy-MM-dd"));
			logs.append(" --> ");
			logs.append(this.datetimeFormate(now.getContractStart(), "yyyy-MM-dd"));
			modify = true;
		}
		if (!this.isDataEqual(old.getContractEnd(), now.getContractEnd(), "yyyy-MM-dd")) {
			logs.append("\n合同结束工期：");
			logs.append(this.datetimeFormate(old.getContractEnd(), "yyyy-MM-dd"));
			logs.append(" --> ");
			logs.append(this.datetimeFormate(now.getContractEnd(), "yyyy-MM-dd"));
			modify = true;
		}
		if (!this.isDataEqual(old.getContractDays(), now.getContractDays())) {
			logs.append("\n工期天数：");
			logs.append(old.getContractDays());
			logs.append(" --> ");
			logs.append(now.getContractDays());
			modify = true;
		}
		if (!this.isDataEqual(old.getCompanyA(), now.getCompanyA())) {
			logs.append("\n建设单位：");
			logs.append(old.getCompanyA());
			logs.append(" --> ");
			logs.append(now.getCompanyA());
			modify = true;
		}
		if (!this.isDataEqual(old.getCompanyB(), now.getCompanyB())) {
			logs.append("\n承建单位：");
			logs.append(old.getCompanyB());
			logs.append(" --> ");
			logs.append(now.getCompanyB());
			modify = true;
		}
		if (!this.isDataEqual(old.getJiesuanWay(), now.getJiesuanWay())) {
			logs.append("\n结算方式：");
			logs.append(old.getJiesuanWay());
			logs.append(" --> ");
			logs.append(now.getJiesuanWay());
			modify = true;
		}
		if (!this.isDataEqual(old.getFukuanWay(), now.getFukuanWay())) {
			logs.append("\n付款方式：");
			logs.append(old.getFukuanWay());
			logs.append(" --> ");
			logs.append(now.getFukuanWay());
			modify = true;
		}
		if (!this.isDataEqual(old.getSignDate(), now.getSignDate(), "yyyy-MM-dd")) {
			logs.append("\n签订日期：");
			logs.append(this.datetimeFormate(old.getSignDate(), "yyyy-MM-dd"));
			logs.append(" --> ");
			logs.append(this.datetimeFormate(now.getSignDate(), "yyyy-MM-dd"));
			modify = true;
		}
		if (!this.isDataEqual(old.getRemark(), now.getRemark())) {
			logs.append("\n备注：");
			logs.append(old.getRemark());
			logs.append(" --> ");
			logs.append(now.getRemark());
			modify = true;
		}
		if (!this.isDataEqual(old.getMainContent(), now.getMainContent())) {
			logs.append("\n工程内容：");
			logs.append(old.getMainContent());
			logs.append(" --> ");
			logs.append(now.getMainContent());
			modify = true;
		}
		if (!this.isDataEqual(old.getChengbaoFanwei(), now.getChengbaoFanwei())) {
			logs.append("\n承包范围：");
			logs.append(old.getChengbaoFanwei());
			logs.append(" --> ");
			logs.append(now.getChengbaoFanwei());
			modify = true;
		}

		if (!modify)
			return null;

		log.setLogs(logs.toString());

		return log;
	}

	private boolean compareBiddingerInfo(BiddingerInfo old, BiddingerInfo now, StringBuilder logs) {
		// 同一个对象或者同为null
		if (old == now)
			return false;

		if (old == null)
			old = new BiddingerInfo();
		if (old.getBiddinger() == null)
			old.setBiddinger(new Biddinger());

		if (now == null)
			now = new BiddingerInfo();
		if (now.getBiddinger() == null)
			now.setBiddinger(new Biddinger());

		boolean modify = false;

		if (!this.isDataEqual(old.getBiddinger().getId(), now.getBiddinger().getId())) {
			logs.append("\n招标单位：");
			logs.append(this.getBiddingerCompany(old.getBiddinger().getId()));
			logs.append(" --> ");
			logs.append(this.getBiddingerCompany(now.getBiddinger().getId()));
			modify = true;
		}
		if (!this.isDataEqual(old.getContact(), now.getContact())) {
			logs.append("\n招标单位联系人：");
			logs.append(old.getContact());
			logs.append(" --> ");
			logs.append(now.getContact());
			modify = true;
		}
		if (!this.isDataEqual(old.getPhone(), now.getPhone())) {
			logs.append("\n招标单位联系电话：");
			logs.append(old.getPhone());
			logs.append(" --> ");
			logs.append(now.getPhone());
			modify = true;
		}

		return modify;
	}

	private boolean compareBidAgencyInfo(BidAgencyInfo old, BidAgencyInfo now, StringBuilder logs) {
		// 同一个对象或者同为null
		if (old == now)
			return false;

		if (old == null)
			old = new BidAgencyInfo();
		if (old.getAgency() == null)
			old.setAgency(new BidAgency());

		if (now == null)
			now = new BidAgencyInfo();
		if (now.getAgency() == null)
			now.setAgency(new BidAgency());

		boolean modify = false;

		if (!this.isDataEqual(old.getAgency().getId(), now.getAgency().getId())) {
			logs.append("\n代理机构：");
			logs.append(this.getBidAgencyCompany(old.getAgency().getId()));
			logs.append(" --> ");
			logs.append(this.getBidAgencyCompany(now.getAgency().getId()));
			modify = true;
		}
		if (!this.isDataEqual(old.getContact(), now.getContact())) {
			logs.append("\n代理机构联系人：");
			logs.append(old.getContact());
			logs.append(" --> ");
			logs.append(now.getContact());
			modify = true;
		}
		if (!this.isDataEqual(old.getPhone(), now.getPhone())) {
			logs.append("\n代理机构电话：");
			logs.append(old.getPhone());
			logs.append(" --> ");
			logs.append(now.getPhone());
			modify = true;
		}

		return modify;
	}

	private DmOpLog newLog(DmOpTypes type) {
		if (this.getUser() == null)
			return null;

		DmOpLog log = new DmOpLog();

		log.setType(type);
		log.setOperator(this.getUser().getFullName());
		log.setTime(new Date());

		return log;
	}

	private boolean isDataEqual(String d1, String d2) {
		if (d1 == null && d2 == null)
			return true;

		if (d1 == null)
			return false;

		if (d2 == null)
			return false;

		return d1.equals(d2);
	}

	private boolean isDataEqual(Date d1, Date d2, String pattern) {
		if (d1 == null && d2 == null)
			return true;

		if (d1 == null)
			return false;

		if (d2 == null)
			return false;

		String s1 = this.datetimeFormate(d1, pattern);
		String s2 = this.datetimeFormate(d2, pattern);

		return this.isDataEqual(s1, s2);
	}

	private boolean isDataEqual(Double d1, Double d2) {
		if (d1 == null && d2 == null)
			return true;

		if (d1 == null)
			return false;

		if (d2 == null)
			return false;

		return d1.equals(d2);
	}

	private boolean isDataEqual(Integer d1, Integer d2) {
		if (d1 == null && d2 == null)
			return true;

		if (d1 == null)
			return false;

		if (d2 == null)
			return false;

		return d1.equals(d2);
	}

	private String datetimeFormate(Date date, String pattern) {
		if (date == null)
			return null;

		if (StringUtils.isBlank(pattern))
			pattern = "yyyy-MM-dd HH:mm:ss.S";

		SimpleDateFormat sdf = new SimpleDateFormat(pattern);

		return sdf.format(date);
	}

	private String getBiddingerCompany(String id) {
		if (StringUtils.isBlank(id))
			return "";

		String ql = "SELECT T.company FROM Biddinger T WHERE T.id = ?";

		String company = (String) this.biddingerSrv.readSingleByQL(ql, id);

		return StringUtils.isBlank(company) ? "" : company;
	}

	private String getBidAgencyCompany(String id) {
		if (StringUtils.isBlank(id))
			return "";

		String ql = "SELECT T.company FROM BidAgency T WHERE T.id = ?";

		String company = (String) this.bidAgencySrv.readSingleByQL(ql, id);

		return StringUtils.isBlank(company) ? "" : company;
	}

}
